
/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_connect.h"
#include "lwip/sockets.h"

#include "oc_mqtt.h"
#include "E53_SC2.h"



#include <math.h>
#include "wifiiot_gpio_ex.h"
#include "wifiiot_errno.h"
#include "wifiiot_adc.h"

#define ADC_TASK_STACK_SIZE 1024 * 8
#define ADC_TASK_PRIO 24


#define MSGQUEUE_OBJECTS 16 // number of Message Queue Objects

typedef struct
{ // object data type
    char *Buf;
    uint8_t Idx;
} MSGQUEUE_OBJ_t;

MSGQUEUE_OBJ_t msg;
osMessageQueueId_t mid_MsgQueue; // message queue id

//连接华为云IOT平台，获取CLIENT_ID、USERNAME、PASSWORD
#define CLIENT_ID "618bbb6ed0a1830285d59e2c_pjs_xxp_0_0_2021111012"//设备ID
#define USERNAME "618bbb6ed0a1830285d59e2c_pjs_xxp"//设备名称
#define PASSWORD "c3dc69564fe558ac769cffb8630d82286cdb3f9d80c20483a2202ccd9a8c37df"//设备密码

typedef enum
{
    en_msg_cmd = 0,
    en_msg_report,
} en_msg_type_t;

typedef struct
{
    char *request_id;
    char *payload;
} cmd_t;

typedef struct
{
    int temp;
    int mus;
    int acc_x; 
    //定义加速度传感器的X轴上的数据
    int acc_y; 
    //定义加速度传感器的Y轴上的数据
    int acc_z; 
    //定义加速度传感器的Z轴上的数据
    int bd_1;
    int bd_2;
    int bd_3;
    int bd_4;
    int bd_5;

} report_t;

typedef struct
{
    en_msg_type_t msg_type;
    union
    {
        cmd_t cmd;
        report_t report;
    } msg;
} app_msg_t;

E53_SC2_Data_TypeDef E53_SC2_Data;

// int X = 0,Y = 0,Z = 0, Cover_Status = 0;

/***** 获取电压值函数 *****/
static float GetVoltage(int i)
{
    unsigned int ret;
    // unsigned short data;
    unsigned short   data[6];
    WifiIotAdcChannelIndex adc_channel[6] = {WIFI_IOT_ADC_CHANNEL_3,WIFI_IOT_ADC_CHANNEL_5,WIFI_IOT_ADC_CHANNEL_1,WIFI_IOT_ADC_CHANNEL_2,WIFI_IOT_ADC_CHANNEL_4,WIFI_IOT_ADC_CHANNEL_0};

    ret = AdcRead(adc_channel[i], &data[i], WIFI_IOT_ADC_EQU_MODEL_8, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("ADC Read Fail\n");
    }

    return (float)data[i] * 1.8 * 4 / 4096.0;
}

//数据上报处理函数
static void deal_report_msg(report_t *report)
{
    //定义用于拼装JSON数据的变量
    oc_mqtt_profile_service_t service;//上传服务名称
    oc_mqtt_profile_kv_t temperature;//上传加速度传感器获取的温度数据
    oc_mqtt_profile_kv_t muscle;
    oc_mqtt_profile_kv_t accel_x;
    oc_mqtt_profile_kv_t accel_y;
    oc_mqtt_profile_kv_t accel_z;
    oc_mqtt_profile_kv_t bend_1;
    oc_mqtt_profile_kv_t bend_2;
    oc_mqtt_profile_kv_t bend_3;
    oc_mqtt_profile_kv_t bend_4;
    oc_mqtt_profile_kv_t bend_5;

    // oc_mqtt_profile_kv_t led;
    // oc_mqtt_profile_kv_t motor;

    //添加初始化服务代码
    service.event_time = NULL;
    //service.service_id = "Agriculture";
    service.service_id = "帕金森&宠物&传感器";//需要和自己设定的设备名称保持一致
    service.service_property = &temperature;
    service.nxt = NULL;

    temperature.key = "Temperature";
    temperature.value = &report->temp;
    temperature.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    temperature.nxt = &muscle;

    muscle.key = "Muscle";
    muscle.value = &report->mus;
    muscle.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    muscle.nxt = &accel_x;

    accel_x.key = "Accel_x";
    accel_x.value = &report->acc_x;
    accel_x.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    accel_x.nxt = &accel_y;

    accel_y.key = "Accel_y";
    accel_y.value = &report->acc_y;
    accel_y.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    accel_y.nxt = &accel_z;

    accel_z.key = "Accel_z";
    accel_z.value = &report->acc_z;
    accel_z.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    accel_z.nxt = &bend_1;

    bend_1.key = "Bend_1";
    bend_1.value = &report->bd_1;
    bend_1.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    bend_1.nxt = &bend_2;

    bend_2.key = "Bend_2";
    bend_2.value = &report->bd_2;
    bend_2.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    bend_2.nxt = &bend_3;

    bend_3.key = "Bend_3";
    bend_3.value = &report->bd_3;
    bend_3.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    bend_3.nxt = &bend_4;

    bend_4.key = "Bend_4";
    bend_4.value = &report->bd_4;
    bend_4.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    bend_4.nxt = &bend_5;

    bend_5.key = "Bend_5";
    bend_5.value = &report->bd_5;
    bend_5.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    bend_5.nxt = NULL;


    oc_mqtt_profile_propertyreport(USERNAME, &service);
    return;
}


static int task_main_entry(void)
{
    app_msg_t *app_msg;

    uint32_t ret = WifiConnect("CMCC-jCK4", "gwtpirte");//连接WiFi

    device_info_init(CLIENT_ID, USERNAME, PASSWORD);//设备初始化
    oc_mqtt_init();//mqtt初始化

    while (1)
    {
        app_msg = NULL;
        (void)osMessageQueueGet(mid_MsgQueue, (void **)&app_msg, NULL, 0U);
        if (NULL != app_msg)
        {
            switch (app_msg->msg_type)
            {
            case en_msg_report:
                deal_report_msg(&app_msg->msg.report);
                break;
            default:
                break;
            }
            free(app_msg);
        }
    }
    return 0;
}

static int task_sensor_entry(void)
{
    app_msg_t *app_msg;
    unsigned int ret;
    unsigned short   data;
    float voltage,voltage_1,voltage_2,voltage_3,voltage_4,voltage_5;  // 1个肌电信号 5个弯曲信号 
    E53_SC2_Init();//初始化加速度数据

    IoSetPull(WIFI_IOT_IO_NAME_GPIO_7, WIFI_IOT_IO_PULL_UP); // ADC3 引脚7  此ADC不用


    // IoSetPull(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_PULL_UP); // ADC6  voltage  引脚13  肌电传感器
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_PULL_UP); //ADC5  voltage_1 引脚11  弯曲传感器1
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_4, WIFI_IOT_IO_PULL_UP); // ADC1  voltage_2 引脚4  弯曲传感器2
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_PULL_UP); // ADC2  voltage_3 引脚5  弯曲传感器3
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_PULL_UP); // ADC4  voltage_4 引脚9  弯曲传感器4
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_IO_PULL_UP); // ADC0  voltage_5 引脚12  弯曲传感器5
    

    while (1)
    {
        
        //弯曲传感器数据
        printf("=======================================\r\n");
        printf("***************ADC_example*************\r\n");
        printf("=======================================\r\n");
        
        voltage   = GetVoltage(0); // ADC6  肌电传感器
        voltage_1 = GetVoltage(1); // ADC5  弯曲传感器1
        voltage_2 = GetVoltage(2); // ADC1  弯曲传感器2
        voltage_3 = GetVoltage(3); // ADC2  弯曲传感器3
        voltage_4 = GetVoltage(4); // ADC4  弯曲传感器4
        voltage_5 = GetVoltage(5); // ADC0  弯曲传感器5


        printf("vlt:%.3fV %.3fV %.3fV %.3fV %.3fV %.3fV\n",voltage,voltage_1,voltage_2,voltage_3,voltage_4,voltage_5);

        //加速度数据和温度数据
        // printf("=======================================\r\n");
        // printf("***********加速度数据和温度数据**********\r\n");
        // printf("=======================================\r\n");
   
        E53_SC2_Read_Data();


        // 开始将数据按照格式Put消息队列
        app_msg = malloc(sizeof(app_msg_t)); 
        if (NULL != app_msg)
        {
            app_msg->msg_type = en_msg_report;
            app_msg->msg.report.temp = (int)E53_SC2_Data.Temperature;
            //上传加速度X轴数据
            app_msg->msg.report.acc_y = (int)E53_SC2_Data.Accel[1];
            //上传加速度Y轴数据
            app_msg->msg.report.acc_z = (int)E53_SC2_Data.Accel[2];
            //上传加速度Z轴数据
            app_msg->msg.report.mus = (int)voltage;
            app_msg->msg.report.bd_1 = (int)voltage_1;
            app_msg->msg.report.bd_2 = (int)voltage_2;
            app_msg->msg.report.bd_3 = (int)voltage_3;
            app_msg->msg.report.bd_4 = (int)voltage_4;
            app_msg->msg.report.bd_5 = (int)voltage_5;

            if (0 != osMessageQueuePut(mid_MsgQueue, &app_msg, 0U, 0U))
            {
                free(app_msg);
            }
        }
        sleep(2);  
    
    }
    return 0;
}

static void OC_Demo(void)
{
    mid_MsgQueue = osMessageQueueNew(MSGQUEUE_OBJECTS, 10, NULL);
    if (mid_MsgQueue == NULL)
    {
        printf("Falied to create Message Queue!\n");
    }

    osThreadAttr_t attr;

    attr.name = "task_main_entry";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 24;

    if (osThreadNew((osThreadFunc_t)task_main_entry, NULL, &attr) == NULL)
    //判断是否成功创建任务task_main_entry
    {
        printf("Falied to create task_main_entry!\n");
    }
    attr.stack_size = 2048;
    attr.priority = 25;
    attr.name = "task_sensor_entry";
    if (osThreadNew((osThreadFunc_t)task_sensor_entry, NULL, &attr) == NULL)
    {
        printf("Falied to create task_sensor_entry!\n");
    }
}

APP_FEATURE_INIT(OC_Demo);//调用OC_Demo函数